from django.db.models.query import DateQuerySet as is_valid_query_object
from django.forms import ModelForm as is_valid_form_object
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.contrib.auth.models import User
from django.http import HttpResponse, HttpResponseForbidden
from django.conf import settings

from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext

from profiles.models import Profile
from profiles.forms import ProfileForm

from avatar.templatetags.avatar_tags import avatar

try:
    from friends.forms import InviteFriendForm
except ImportError:
    InviteFriendForm = None
    
try:
    from friends.models import FriendshipInvitation, Friendship
except ImportError:
    FriendshipInvitation = None
    Friendship = None

try:
    from microblogging.models import Following
except ImportError:
    Following = None


def profiles(request, template_name="profiles/profiles.html"):
    return render_to_response(template_name, {
        "users": User.objects.all().order_by("-date_joined"),
    }, context_instance=RequestContext(request))

def profile(request, username, template_name="profiles/profile.html"):
    """ Display the profile and the associated form.
        TODO: Most of the logic here should be functionized and placed into
                a base_profiles object. Then this profile method or other ones
                could call the functions as needed rather than this big god method. 
    
    """
    
    # Should we use a different template?
    if 'app_plugins' not in settings.INSTALLED_APPS:    
        template_name = 'profiles/profile_no_plugins.html'
    
    other_user = get_object_or_404(User, username=username)
    
    
    if request.user.is_authenticated():
        if request.user == other_user:
            is_me = True
        else:
            is_me = False        
        
        # We do very simple try/excepts on the elements below because 
        # if these items are not include in your Pinax project then they 
        # throw database specific errors. Django methodology is that we do
        # not code to specific databases, so we just rely on as generic errors
        # as possible
        try:
            is_friend = Friendship.objects.are_friends(request.user, other_user)
        except:
            is_friend = False

        try:
            other_friends = Friendship.objects.friends_for_user(other_user)
        except:
            other_friends = []
            
        try:
            is_following = Following.objects.is_following(request.user, other_user)
        except AttributeError:
            is_following = []   
                     

    else:
        other_friends = []
        is_friend = False
        is_me = False
        is_following = False
    
    if is_friend:
        invite_form = None
        previous_invitations_to = None
        previous_invitations_from = None
    else:
        if request.user.is_authenticated() and request.method == "POST":
            if request.POST["action"] == "invite":
                invite_form = InviteFriendForm(request.user, request.POST)
                if invite_form.is_valid():
                    invite_form.save()
            else:
                invite_form = InviteFriendForm(request.user, {
                    'to_user': username,
                    'message': ugettext("Let's be friends!"),
                })
                if request.POST["action"] == "accept": # @@@ perhaps the form should just post to friends and be redirected here
                    invitation_id = request.POST["invitation"]
                    try:
                        invitation = FriendshipInvitation.objects.get(id=invitation_id)
                        if invitation.to_user == request.user:
                            invitation.accept()
                            request.user.message_set.create(message=_("You have accepted the friendship request from %(from_user)s") % {'from_user': invitation.from_user})
                            is_friend = True
                            other_friends = Friendship.objects.friends_for_user(other_user)
                    except FriendshipInvitation.DoesNotExist:
                        pass
        else:
            invite_form = InviteFriendForm(request.user, {
                'to_user': username,
                'message': ugettext("Let's be friends!"),
            })  

            # This is executed to determine if the InviteFriendForm actually
            # exists, since Django/Pinax thinks the module actually exists. 
            if not isinstance(invite_form,is_valid_form_object):
                invite_form = None
            
    # We need to confirm that previous_invitations_to is a real query object
    # otherwise the page template throws an error
    previous_invitations_to = FriendshipInvitation.objects.filter(to_user=other_user, from_user=request.user)
    if not isinstance(previous_invitations_to,is_valid_query_object):
        previous_invitations_to = []

    # We need to confirm that previous_invitations_from is a real query object
    # otherwise the page template throws an error
    previous_invitations_from = FriendshipInvitation.objects.filter(to_user=request.user, from_user=other_user)
    if not isinstance(previous_invitations_from,is_valid_query_object):
        previous_invitations_from = []    

    
    if is_me:
        if request.method == "POST":
            if request.POST["action"] == "update":
                profile_form = ProfileForm(request.POST, instance=other_user.get_profile())
                if profile_form.is_valid():
                    profile = profile_form.save(commit=False)
                    profile.user = other_user
                    profile.save()
            else:
                profile_form = ProfileForm(instance=other_user.get_profile())
        else:
            profile_form = ProfileForm(instance=other_user.get_profile())
    else:
        profile_form = None

    return render_to_response(template_name, {
        "profile_form": profile_form,
        "is_me": is_me,
        "is_friend": is_friend,
        "is_following": is_following,
        "other_user": other_user,
        "other_friends": other_friends,
        "invite_form": invite_form,
        "previous_invitations_to": previous_invitations_to,
        "previous_invitations_from": previous_invitations_from,
    }, context_instance=RequestContext(request))
